package display3d.alternativa {
	import alternativa.engine3d.core.Object3D;
	import alternativa.engine3d.loaders.ParserCollada;
	import alternativa.engine3d.materials.FillMaterial;
	import alternativa.engine3d.objects.Skin;

	import jazztures.geom.Point3D;
	import jazztures.objects.Skeleton;
	import jazztures.utils.GeometryUtils;

	import flash.geom.Vector3D;

	public class Mario3D extends Doll3D
	{
		[Embed(source="../assets/char_model.dae",mimeType="application/octet-stream")]
		private var MarioModel:Class;
			
		[Embed(source="../assets/mario_texture.jpg")]
		private var MarioTexture:Class;
		
		protected var model:Skin;                                                                                                                                                                                      
		
		public function Mario3D()
		{
			super();
		}
		
		override protected function build():void{
			var collada:ParserCollada= new ParserCollada();
			collada.parse(new XML(new MarioModel()));
			
			for(var i in collada.materials){
				trace(collada.materials[i]);
			}
			
			model = Skin(collada.getObjectByName("character"));
			
												
			addChild(model);
			
			setMaterial();

//			head3D = model.getBoneByName("head");
			neck3D = model.getJointByName("neck");
			torso3D = model.getJointByName("torso");
//			
//			leftShoulder3D = model.getBoneByName("leftShoulder");
//			leftElbow3D = model.getBoneByName("leftElbow");
//			
//			rightShoulder3D = model.getBoneByName("rightShoulder");
//			rightElbow3D = model.getBoneByName("rightElbow");
//			
//			leftHip3D = model.getBoneByName("leftHip");
//			
//			rightHip3D = model.getBoneByName("rightHip");
		}
		
		protected function setMaterial():void{
			var material:FillMaterial = new FillMaterial(0xFF0000, 1, 1, 0x000000);
//			var material:TextureMaterial = new TextureMaterial(new MarioTexture());;
			model.setMaterialToAllFaces(material);
//			model.materialLibrary.getMaterial("FF_FF_FF_mario1").material = new BitmapMaterial(Cast.bitmap(MarioTexture));
		}
		
		override public function set skeleton(skeleton:Skeleton):void{
			super.skeleton = skeleton;
			
			clearRotations(head);
			clearRotations(neck);
			clearRotations(torso);
			
			clearRotations(leftShoulder);
			clearRotations(leftElbow);
			clearRotations(leftHand);
			
			clearRotations(leftHip);
			clearRotations(leftKnee);
			clearRotations(leftFoot);
			
			clearRotations(rightShoulder);
			clearRotations(rightElbow);
			clearRotations(rightHand);
			
			clearRotations(rightHip);
			clearRotations(rightKnee);
			clearRotations(rightFoot);
			
			neck.rotationY = getYaw(leftShoulder.vector3D, rightShoulder.vector3D) + 90;

			var torsoRP:Vector3D = getRP(torso.vector3D, neck);
			
			normalizeRotations(neck);
			neck.rotationZ = (neck.rotationY>90 && neck.rotationY<270 ? -1:1) * getYaw(new Vector3D(), torsoRP, "x", "y")  + 180;
			
			normalizeRotations(neck);
			torsoRP = getRP(torso.vector3D, neck);
			neck.rotationX = -getYaw(new Vector3D(), torsoRP, "y", "z") -90;
			normalizeRotations(neck);

		
			var lKneeRP:Vector3D = getRP(leftKnee.vector3D, neck);
			var rKneeRP:Vector3D = getRP(rightKnee.vector3D, neck);
			torsoRP = getRP(torso.vector3D, neck);
			var waistRP:Vector3D = getRP(GeometryUtils.getMiddlePoint(leftHip.vector3D, rightHip.vector3D), neck);
			torso.rotationX = -getYaw(waistRP, torsoRP, "y", "z") +90;
			torso.rotationY = getYaw(lKneeRP, rKneeRP) + 90;
			torso.rotationZ = -getYaw(torsoRP, new Vector3D(), "x", "y");


			
			neck.y = Math.max(leftFoot.y,rightFoot.y) -190;
		}
		
		override public function update():void{
			setPositionAndRotation(neck3D, neck);
			
//			setRotation(head3D, getRotation(head));
//			
//			setRotation(leftShoulder3D, getRotation(leftShoulder));
//			setRotation(leftElbow3D, getRotation(leftElbow));
//
//			setRotation(rightShoulder3D, getRotation(rightShoulder));
//			setRotation(rightElbow3D, getRotation(rightElbow));
//			
//			setRotation(torso3D, getRotation(torso));
//			
//			setRotation(leftHip3D, getRotation(leftHip));
//			setRotation(rightHip3D, getRotation(rightHip));

			setPositionAndRotation(torso3D, torso);
		}
		
		private function clearRotations(obj:Point3D):void{
			obj.rotationX = 0;
			obj.rotationY = 0;
			obj.rotationZ = 0;
			
			obj.z = obj.z/10;
		}
		
		override protected function setRotation(obj:Object3D, source:Point3D):void{
//			Bone(obj).jointRotationX = source.x;
//			Bone(obj).jointRotationY = source.y;
//			Bone(obj).jointRotationZ = source.z;
		}
		
		private function getRotation(object:Point3D):Vector3D{
			return new Vector3D(object.rotationX, object.rotationY, object.rotationZ);
		}
		
		private function getRP(target:Vector3D, source:Point3D):Vector3D{
			return GeometryUtils.getRelativePosition(target, source);
		}
		
		private function normalizeRotations(point:Point3D):void{
			point.rotationX = normalizeRotation(point.rotationX);
			point.rotationY = normalizeRotation(point.rotationY);
			point.rotationZ = normalizeRotation(point.rotationZ);
		}
		
		private function normalizeRotation(degrees:Number):Number{
			degrees = degrees % 360;
			if(degrees < 0) degrees += 360;
			return degrees;
		}
		
		private function getYaw(origin:Vector3D, target:Vector3D, baseParam1:String = "x", baseParam2:String = "z"):Number{
			return GeometryUtils.getYaw(origin, target, true, baseParam1, baseParam2);
		}
		
		private function getPitch(origin:Vector3D, target:Vector3D, baseParam1:String = "x", baseParam2:String = "y", baseParam3:String = "z"):Number{
			return GeometryUtils.getPitch(origin, target, true, baseParam1, baseParam2, baseParam3);
		}
	}
}